package component

import (
	"TheTearAfter/models"
	"TheTearAfter/util"
	"fmt"
	"sync"

	"golang.org/x/net/html"
)

/**
 * @File : messageClawer.go
 * @Description : 信息爬取
 * @Author : chen
 * @Date : 2024/4/9
 */

// 信息爬虫
type MessageClawer struct {
	baseUrl string
	urlList models.MessageUrlList
	messageList models.MessageBlockSyncList
}

// 获取列表
func (MC *MessageClawer) GetUrlList() []string {
	return MC.urlList.GetList()
}

// 爬 信息块的 url
func (MC *MessageClawer) ClawUrl(pageNum int, className string) (urlList []string, err error) {
	// 每个协程最大 1 个任务
	taskList := util.CalcTask(1, pageNum)
	var wg sync.WaitGroup

	nowPage := 1
	for _, taskNum := range taskList {
		wg.Add(1)
		// 利用闭包保存起始位置
		go func(starPage, nowtask int) {
			defer wg.Done()
			for i := 0; i < nowtask; i++ {
				// 获取 HTML
				HTMLData, err := util.FetchHTML(fmt.Sprintf(MC.baseUrl, starPage+i))
				if err != nil {
					fmt.Println("MC.fetchHTML err", err)
					return
				}
				// 添加 url
				MC.urlList.Add(util.GetAttrFromClass(HTMLData, className, "href"))
			}
		}(nowPage, taskNum)

		nowPage += taskNum
	}
	wg.Wait()

	urlList = MC.GetUrlList()
	return
}

func (MC *MessageClawer) fillMessage(url string, n *html.Node) (*models.MessageBlock) {
	message := models.NewMessageBlock()

	message.Link = url

	imgList := util.GetAttrFromType(n, "img", "src")
	firstImg := util.FindFirstNodeByType(n, "img")

	altList := util.GetAttrFromType(firstImg, "img", "alt")

	if len(altList) > 0 && altList[0] != "Share to facebook" {
		message.Img = imgList[0]
	} else if len(imgList) > 5 {
		message.Img = imgList[5]
	}

	timeList := util.GetTextFromClass(n, "wp-block-post-date")
	if len(timeList) > 0 {
		message.Time = timeList[0]
	}

	titleList := util.GetTextFromClass(n, "wp-block-post-title")
	if len(titleList) > 0 {
		message.Title = titleList[0]
	}

	fromList := util.GetTextFromClass(n, "wp-block-post-author__name")
	if len(fromList) > 0 {
		message.From = fromList[0]
	}

	return &message
}

// 获取信息块
func (MC *MessageClawer) ClawMessage() (messageList []*models.MessageBlock, err error) {
	// 每个协程最大 3 个任务
	taskList := util.CalcTask(3, MC.urlList.GetLen())
	var wg sync.WaitGroup
	// 当前的列表
	urlList := MC.urlList.GetList()

	nowUrl := 0
	for _, taskNum := range taskList {
		wg.Add(1)
		go func(starUrl, nowTask int) {
			defer wg.Done()
			list := []*models.MessageBlock{}
			for i := 0; i < nowTask; i++ {
				// 获取 HTML

				HTMLData, err := util.FetchHTML(urlList[starUrl + i])
				if err != nil {
					fmt.Println("MC.fetchHTML err", err)
					return
				}
				// 添加筛选条件
				list = append(list, MC.fillMessage(urlList[starUrl + i], HTMLData))
			}
			MC.messageList.Add(list)
		}(nowUrl, taskNum)

		nowUrl += taskNum
	}
	wg.Wait()

	messageList = MC.messageList.GetList()
	return
}

func NewMessageClawer(baseUrl string) MessageClawer {
	return MessageClawer{
		baseUrl: baseUrl,
	}
}
